<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Carbon\Carbon;

class Payment extends Model
{
    use HasFactory;

    protected $fillable = [
        'order_id',
        'payment_method',
        'transaction_id',
        'amount',
        'status',
        'payment_data',
        'failure_reason',
        'paid_at',
        'expires_at',
    ];

    protected $casts = [
        'payment_data' => 'array',
        'paid_at' => 'datetime',
        'expires_at' => 'datetime',
        'amount' => 'decimal:2',
    ];

    // 支付状态常量
    const STATUS_PENDING = 'pending';
    const STATUS_PAID = 'paid';
    const STATUS_FAILED = 'failed';
    const STATUS_REFUNDED = 'refunded';
    const STATUS_CANCELLED = 'cancelled';

    // 支付方式常量
    const METHOD_ALIPAY = 'alipay';
    const METHOD_WECHAT = 'wechat';
    const METHOD_MOCK = 'mock'; // 模拟支付

    /**
     * 关联订单
     */
    public function order(): BelongsTo
    {
        return $this->belongsTo(Order::class);
    }

    /**
     * 检查支付是否已过期
     */
    public function isExpired(): bool
    {
        return $this->expires_at && $this->expires_at->isPast();
    }

    /**
     * 检查支付是否成功
     */
    public function isPaid(): bool
    {
        return $this->status === self::STATUS_PAID;
    }

    /**
     * 检查支付是否失败
     */
    public function isFailed(): bool
    {
        return $this->status === self::STATUS_FAILED;
    }

    /**
     * 检查支付是否待处理
     */
    public function isPending(): bool
    {
        return $this->status === self::STATUS_PENDING;
    }

    /**
     * 标记为已支付
     */
    public function markAsPaid(string $transactionId = null): void
    {
        $this->update([
            'status' => self::STATUS_PAID,
            'transaction_id' => $transactionId ?: $this->transaction_id,
            'paid_at' => now(),
        ]);
    }

    /**
     * 标记为失败
     */
    public function markAsFailed(string $reason = null): void
    {
        $this->update([
            'status' => self::STATUS_FAILED,
            'failure_reason' => $reason,
        ]);
    }

    /**
     * 标记为已退款
     */
    public function markAsRefunded(): void
    {
        $this->update([
            'status' => self::STATUS_REFUNDED,
        ]);
    }

    /**
     * 获取支付方式显示名称
     */
    public function getPaymentMethodNameAttribute(): string
    {
        return match($this->payment_method) {
            self::METHOD_ALIPAY => '支付宝',
            self::METHOD_WECHAT => '微信支付',
            self::METHOD_MOCK => '模拟支付',
            default => '未知支付方式',
        };
    }

    /**
     * 获取状态显示名称
     */
    public function getStatusNameAttribute(): string
    {
        return match($this->status) {
            self::STATUS_PENDING => '待支付',
            self::STATUS_PAID => '已支付',
            self::STATUS_FAILED => '支付失败',
            self::STATUS_REFUNDED => '已退款',
            self::STATUS_CANCELLED => '已取消',
            default => '未知状态',
        };
    }

    /**
     * 创建支付记录
     */
    public static function createForOrder(Order $order, string $paymentMethod, array $options = []): self
    {
        $expiresAt = $options['expires_at'] ?? now()->addMinutes(30);
        
        return self::create([
            'order_id' => $order->id,
            'payment_method' => $paymentMethod,
            'amount' => $order->total_amount,
            'status' => self::STATUS_PENDING,
            'expires_at' => $expiresAt,
            'payment_data' => $options['payment_data'] ?? [],
        ]);
    }

    /**
     * 模拟支付处理（用于学习项目）
     */
    public function processMockPayment(): array
    {
        if ($this->payment_method !== self::METHOD_MOCK) {
            throw new \InvalidArgumentException('只能处理模拟支付');
        }

        // 模拟支付处理时间
        sleep(2);

        // 模拟支付结果（90% 成功，10% 失败）
        $isSuccess = rand(1, 10) <= 9;
        
        if ($isSuccess) {
            $this->markAsPaid('MOCK_' . time() . '_' . rand(1000, 9999));
            return [
                'success' => true,
                'message' => '支付成功',
                'transaction_id' => $this->transaction_id,
            ];
        } else {
            $this->markAsFailed('模拟支付失败');
            return [
                'success' => false,
                'message' => '支付失败，请重试',
                'error' => '模拟支付失败',
            ];
        }
    }
}